package com.xxxx.server.config.security.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.*;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import java.util.ArrayList;
import java.util.List;

@Configuration
@EnableSwagger2
public class Swagger2Config {
    /*
    参考
    https://blog.csdn.net/fjscqjj1/article/details/79974472*/
    @Bean
    public Docket createRestApi(){
        //文档类型SWAGGER_2
        return new Docket(DocumentationType.SWAGGER_2)
                //信息接口
                .apiInfo(apiInfo())
                .select()
                //扫描此包进行监控
                .apis(RequestHandlerSelectors.basePackage("com.xxxx.server.controller"))
                //对所有路径进行api监控
                .paths(PathSelectors.any())
                .build()
                .securityContexts(securityContexts())
                .securitySchemes(securitySchemes());
    }
    private ApiInfo apiInfo(){
        return new ApiInfoBuilder()
                .title("云e办")
                .description("云e办接口文档")
                //内容
                .contact(new Contact("xxxx","http:8081/doc.html","xxxx@xxxx.com"))
                .version("1.0")
                .build();
    }
    private List<ApiKey> securitySchemes() {
        List<ApiKey> result = new ArrayList<>();
        ApiKey apiKey = new ApiKey("Authorization", "Authorization", "Header");
        result.add(apiKey);
        return result;
        }
     private List<SecurityContext> securityContexts(){
        //设置需要登录认证的的路径
         List<SecurityContext> result = new ArrayList<>();
         result.add(getContextByPath("/hello/*"));
         return result;
     }
   /*
     .在Swagger2的securityContexts中通过正则表达式，设置需要使用参数的接口
    （或者说，是去除掉不需要使用参数的接口），如下列代码所示，通过PathSelectors.regex(“^(?!auth).*$”)，
    所有包含”auth”的接口不需要使用securitySchemes。
    即不需要使用上文中设置的名为“Authorization”，type为“header”的参数。*/
    private SecurityContext getContextByPath(String pathRegex) {
       return SecurityContext.builder()
               //设置默认权限,全局允许所有
                .securityReferences(defaultAuth())
               //认证的路径,会携带token过去
                .forPaths(PathSelectors.regex("^(?!auth).*$"))//此正则--含auth会不使用我们的authorization参数其他都使用
                .build();
    }
    private List<SecurityReference> defaultAuth() {
        List<SecurityReference> result = new ArrayList<>();
        //全局，允许所有，意思是authorization写一个全局都共用，不用每个接口都写authorization
        AuthorizationScope  authorizationScope=new AuthorizationScope("global","accessEverything");
        AuthorizationScope[] authorizationScopes=new AuthorizationScope[1];
        authorizationScopes[0]=authorizationScope;
        //下面要求要数组才这样
        result.add(new SecurityReference("Authorization",authorizationScopes));
        return  result;
    }
}
